﻿using FittyWars.BordUtils;
using FittyWars.GraphicUtils;
using FittyWars.MathUtil;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FittyWars
{
    public class GameManager
    {
        #region Control States
        public enum ControlState
        {
            Uninitialized,
            Ready,
            Playing,
            Paused,
            Finished,
            Reset
        }
        #endregion

        #region Members
        private Bord m_gameBord;
        private Display m_display;
        private System.Threading.Timer m_mainControlTimer;
        private ControlState m_state;
        private Random m_leafRand;
        private static int seed = 0x9ac4700;
        #endregion

        #region Properties
        public int MainTimerRate { get; set; }
        #endregion

        #region Ctor
        public GameManager()
        {
            SetState(ControlState.Uninitialized);
        }
        #endregion 

        #region Public methods
        public void Initialize(Display display, Bord bord)
        {
            m_display = display;
            m_display.Initialize();
            m_gameBord = bord;
            m_gameBord.Initialize();

            m_gameBord.PolyPlace2();

            //ElzingaHearnTest();

            
            MainTimerRate = 50;
            m_leafRand = new Random(seed++);
            //testInsert();
            SetGameTimer();
            m_gameBord.PlayNextDay();
            m_display.UpdateGameDisplay(m_gameBord.GetElementList());

        }
        public void DebugStep()
        {
            m_gameBord.PlayNextDay();
            m_display.UpdateGameDisplay(m_gameBord.GetElementList());
        }

        public void Play()
        { }
        public void Pause()
        { }
        /*public void Insert(GameElement GE, double posx, double posy)
        {
            switch (GE)
            {
                case GameElement.Fitty :
                    m_gameBord.AddElement(new Fitty(posx, posy, 0xffc3));
                    break;
                case GameElement.Duck :
                    m_gameBord.AddElement(new Duck(posx, posy));
                    break;
                case GameElement.Leaf :
                    m_gameBord.AddElement(new Leaf(posx, posy));
                    break;
                case GameElement.Worm:
                    m_gameBord.AddElement(new Worm(posx, posy));
                    break;
            }
        }*/
        public void Reset()
        { }
        #endregion

        #region Private methods
        private void SetState(ControlState newState)
        {
            m_state = newState;
        }
        private void SetGameTimer()
        {
            m_mainControlTimer = new System.Threading.Timer(
                MainControlTimerCallback,
                null, 300, MainTimerRate);
        }
        private void MainControlTimerCallback(object obj)
        {
            //AddRandomLeaf();
            m_gameBord.PlayNextDay();
            m_display.Invoke(
                new MethodInvoker(
                    delegate()
                    {
                        m_display.UpdateGameDisplay(m_gameBord.GetElementList());
                    }));
        }
        #endregion

        #region Tests
        private void testInsert()
        {
            //Insert(GameElement.Fitty, 10.0, 10.0);
            //Insert(GameElement.Duck, 10.0, 10.0);
            //Insert(GameElement.Duck, 40.0, 40.0);
            //Insert(GameElement.Leaf, 30.0, 30.0);
        }
        public void ElzingaHearnTest()
        {
            int seed = 50;
            int amount = 8;
            double margin = 0.2;
            List<Vector> vectors = new List<Vector>();
            Random rand = new Random(seed);
            for (int i = 0; i < amount; i++)
            {
                vectors.Add( new Vector(
                    margin + (1.0 - 2*margin) * rand.NextDouble(), 
                    margin + (1.0 - 2*margin) * rand.NextDouble() 
                ));
            }
            Circle cc = MathHelper.ElzingaHearn(vectors);
            m_display.ElzingaHearnTestDisplay(vectors, cc);
        }
        /*private void AddRandomLeaf()
        {
            if (m_leafRand.NextDouble() < 0.01)
            {
                Insert(GameElement.Leaf,
                    m_leafRand.NextDouble() * m_gameBord.BordWidth * 0.8,
                    m_leafRand.NextDouble() * m_gameBord.BordHeight * 0.8);
            }
        }*/
        #endregion
    }
}
